<template>
	<view class="ai-ask-container">
		<!-- 自定义导航栏 -->
		<view class="nav-bar" :style="{ paddingTop: statusBarHeight + 'px' }">
			<u-icon name="arrow-left" size="22" @click="goBack"></u-icon>
			<text class="nav-title">AI问问</text>
			<u-icon name="more-dot-fill" size="22"></u-icon>
		</view>

		<!-- 主要内容区域 -->
		<!-- @scrolltoupper="fetchHistory" -->
		<scroll-view scroll-y class="content-scroll"
			:style="{ height: `calc(100vh - ${navBarHeight}px - ${inputBarHeight}px)` }"
			:scroll-into-view="scrollIntoViewId" scroll-with-animation refresher-enabled
			:refresher-triggered="isRefresherTriggered">
			<!-- 头部预留背景图位置 -->
			<view class="header-section">
				<!-- 您可以在这里放置背景图 -->
				<image class="header-bg"
					src="http://www.hacn86.cn/AI_QA/2025/07/10/1752136516884_20250710163516A004.png"></image>
				<image class="ai-avatar"
					src="http://www.hacn86.cn/AI_QA/2025/07/10/1752136551119_20250710163551A006.png" mode="widthFix">
				</image>
				<image class="ai-hi" src="http://www.hacn86.cn/AI_QA/2025/07/10/1752136565833_20250710163605A007.png"
					mode="widthFix"></image>
				<view class="header-content">

					<view class="slogan">
						<view class="slogan-main">旅游攻略管够问，玩啥问我包会答~</view>
					</view>
				</view>
			</view>
			<view class="content-scroll-header">
				<!-- 旅圈热点 -->
				<view class="hot-topics-section">
					<view class="section-title">
						<view class="title-slash">\\</view>
						<text class="title-text">Ai问问带你看旅圈热点</text>
						<view class="title-slash">//</view>
					</view>
					<!-- 修改：使用一个父容器包裹两个独立的滚动行 -->
					<view class="topics-container">
						<!-- 第一行：向左滚动 -->
						<view class="topics-row" :style="{ animationDuration: animationDurationRow1 + 's' }">
							<u-tag v-for="(topic, index) in hotTopicsRow1" :key="" :text="topic" shape="circle"
								bgColor="#ffffff" borderColor="#f5f5f5" color="#000" class="topic-tag"
								@click="sendHotTopic(topic)"></u-tag>
						</view>
						<!-- 第二行：向右滚动 -->
						<view class="topics-row row-reverse"
							:style="{ animationDuration: animationDurationRow2 + 's' }">
							<u-tag v-for="(topic, index) in hotTopicsRow2" :key="" :text="topic" shape="circle"
								bgColor="#ffffff" borderColor="#f5f5f5" color="#000" class="topic-tag"
								@click="sendHotTopic(topic)"></u-tag>
						</view>
					</view>
				</view>

				<!-- 猜您想问 -->
				<view class="suggestions-section">
					<view class="section-title">
						<image class="title-icon" src="/static/common/icon_cnxw.png" mode="widthFix"></image>
						猜您想问
						<view class="refresh-btn" @click="fetchSuggestions">
							<u-icon name="reload" size="14"></u-icon>
							<text>换一批</text>
						</view>
					</view>
					<view class="suggestion-list">
						<view class="suggestion-item" v-for="(q, index) in suggestions" :key="index"
							@click="sendSuggestion(q)">
							<text>{{ q }}</text>
							<u-icon name="arrow-right" color="#cccccc" size="14"></u-icon>
						</view>
					</view>
				</view>
			</view>

			<!-- 聊天记录 -->
			<view class="chat-history">
				<view v-for="(msg, index) in chatHistory" :key="msg.id || index" :id="'msg-' + (msg.id || index)"
					:class="['chat-bubble-wrapper', msg.role]">
					<image v-if="msg.role === 'ai'" class="chat-ai" src="/static/common/ai.png"></image>
					<view class="chat-bubble">
						<!-- 文本消息 -->
						<text v-if="msg.type === 'text'">{{ msg.content }}</text>
						<!-- 新增：图片消息 -->
						<image v-if="msg.type === 'image'" :src="msg.content" class="chat-image" mode="widthFix"
							@click="previewImage(msg.content)"></image>
					</view>
					<image v-if="msg.role === 'user'" class="chat-avatar" :src="$store.state.userInfo.avatar"></image>
				</view>
			</view>

		</scroll-view>

		<!-- 底部输入栏 -->
		<view class="input-bar" ref="inputBar">
			<u-icon name="mic" size="24" customStyle="margin: 0 16rpx;"></u-icon>
			<view class="input-wrapper">
				<input type="text" v-model="currentInput" placeholder="我是你的Ai助手，旅行难题随便抛~" confirm-type="send"
					@confirm="sendMessage" />
			</view>
			<!-- 修改：根据输入内容条件渲染“发送”按钮或“+”号 -->
			<view v-if="currentInput.trim()" class="submit">
				<u-button type="primary" shape="circle" size="small" text="发送" @click="sendMessage" color="#FFAD4A"
					custom-style="margin: 0 16rpx;"></u-button>
			</view>
			<u-icon v-else name="plus" bold size="20" customStyle="margin: 0 16rpx;"
				@click="handleUploadImage"></u-icon>
		</view>
	</view>
</template>

<script>
	// 导入API方法
	import {
		getAiHotTopics,
		getAiSuggestions,
		getAiChatHistory,
		sendAiMessage
	} from '@/request/api.js';
	import imService from '@/utils/imService.js';
	import {
		mapState,
		mapActions
	} from 'vuex';
	// 导入七牛云上传工具
	import {
		uploadFile
	} from '@/utils/qiniuUploader.js';

	const AI_BOT_ID = 'ai_assistant'; // **重要：替换为你环信后台创建的机器人账号ID**
	const MAX_HISTORY_PER_FETCH = 15;


	export default {
		data() {
			return {
				statusBarHeight: 0,
				navBarHeight: 44,
				inputBarHeight: 50,
				/************************************************************ 热点 ************************************************************/
				hotTopicsRow1: [], // 第一行的数据
				hotTopicsRow2: [], // 第二行的数据
				animationDurationRow1: 20, // 第一行的动画时长
				animationDurationRow2: 23, // 第二行的动画时长（略有不同可产生视差效果）
				/************************************************************ *** ************************************************************/
				animationDuration: 20,
				suggestions: [],
				chatHistory: [
					//             {
					//                 id: 'initial_msg',
					// 	role: 'ai',
					// 	type: 'text',
					// 	content: '你好，非常高兴与您交流！旅游界的‘行走攻略库’在此！不管是找美食、挖小众景点还是避雷坑，尽管朝我‘投喂’问题，保证秒变你的专属旅游小雷达~'
					// }
				],
				currentInput: '',
				scrollIntoViewId: '',
				targetUserId: AI_BOT_ID,
				isRefresherTriggered: false,
				replyData: null,
				// 新增/修改的状态
				isLoadingHistory: false, // 标记是否正在加载历史
				isWaitingForAi: false, // 标记是否正在等待AI回复
				isFirstLoad: true, // 标记是否是首次加载
				pageNum: 1, // 历史记录的页码
				canLoadMoreHistory: true, // 是否还有更多历史记录
			};
		},
		computed: {
			...mapState('im', ['imUserId']),
		},
		onLoad() {
			const systemInfo = uni.getSystemInfoSync();
			this.statusBarHeight = systemInfo.statusBarHeight;
			this.fetchHotTopics();
			this.fetchSuggestions();
			// this.fetchHistory(true); // 首次加载历史记录
		},
		onReady() {
			const query = uni.createSelectorQuery().in(this);
			query.select('.input-bar').boundingClientRect(data => {
				if (data) this.inputBarHeight = data.height;
			}).exec();
		},
		onUnload() {},
		methods: {
			goBack() {
				uni.navigateBack();
			},
			async fetchHotTopics() {
				try {
					const res = await getAiHotTopics();
					if (res.data && res.data.data && res.data.data.length > 0) {
						const originalTopics = res.data.data;

						// 1. 将数据拆分成两半
						const splitIndex = Math.ceil(originalTopics.length / 2);
						const topics1 = originalTopics.slice(0, splitIndex);
						const topics2 = originalTopics.slice(splitIndex);

						// 2. 分别为两行的数据进行复制，以实现无缝滚动
						this.hotTopicsRow1 = [...topics1, ...topics1];
						this.hotTopicsRow2 = [...topics2, ...topics2];

						// 也可以根据内容长度动态计算动画时间
						// const totalLength1 = topics1.reduce((sum, item) => sum + item.length, 0);
						// this.animationDurationRow1 = Math.max(15, totalLength1 * 0.5);
						// const totalLength2 = topics2.reduce((sum, item) => sum + item.length, 0);
						// this.animationDurationRow2 = Math.max(18, totalLength2 * 0.5);

					}
				} catch (error) {
					console.error("获取热点话题失败:", error);
				}
			},
			async fetchSuggestions() {
				const res = await getAiSuggestions();
				if (res.data && res.data.data) {
					this.suggestions = res.data.data;
				}
			},
			async fetchHistory(isInitial = false) {
				if (this.isLoadingHistory || !this.canLoadMoreHistory) {
					if (this.isRefresherTriggered) this.isRefresherTriggered = false;
					return;
				}

				this.isLoadingHistory = true;
				if (isInitial) this.isRefresherTriggered = true;

				try {
					const params = {
						pageNum: this.pageNum,
						pageSize: MAX_HISTORY_PER_FETCH
					};
					const res = await getAiChatHistory(params);

					if (res.data && res.data.code === 200) {
						const newMessages = (res.data.rows || []).map(this.formatApiMessage).reverse();

						// 如果是加载更多，记录当前顶部消息ID，用于恢复滚动位置
						const oldTopMsgId = this.chatHistory.length > 0 ? this.chatHistory[0].id : null;

						this.chatHistory = [...newMessages, ...this.chatHistory];

						if (newMessages.length < MAX_HISTORY_PER_FETCH) {
							this.canLoadMoreHistory = false;
						} else {
							this.pageNum++;
						}

						this.$nextTick(() => {
							if (isInitial) {
								this.scrollToBottom();
							} else if (oldTopMsgId) {
								// 滚动到加载前的位置，实现无感加载
								this.scrollIntoViewId = `msg-${oldTopMsgId}`;
							}
						});
					} else {
						this.canLoadMoreHistory = false;
					}
				} catch (error) {
					console.error("加载历史消息失败:", error);
					this.canLoadMoreHistory = false;
				} finally {
					this.isLoadingHistory = false;
					if (this.isRefresherTriggered) this.isRefresherTriggered = false;
				}
			},
			// 用于将后端数据格式化为UI所需格式
			formatApiMessage(apiMsg) {
				// 请根据你的后端API返回的实际字段进行调整
				return {
					id: apiMsg.id, // 假设后端返回 id
					role: apiMsg.senderType === 'USER' ? 'user' : 'ai', // 假设后端用 senderType 区分
					type: apiMsg.messageType, // 'text' or 'image'
					content: apiMsg.content,
					// ... 其他可能需要的字段
				};
			},
			formatMessage(msg) {
				return {
					id: msg.id || msg.localId,
					role: (msg.from === this.imUserId) ? 'user' : 'ai',
					type: 'text',
					content: msg.msg || msg.data || '[暂不支持的消息类型]',
				};
			},
			sendSuggestion(question) {
				this.sendTextMessageToAI(question);
			},
			// 新增：处理点击热点话题的方法
			sendHotTopic(topic) {
				// 直接调用通用的发送文本消息方法
				this.sendTextMessageToAI(topic);
			},
			// 核心：封装一个通用的文本发送逻辑，供 sendMessage, sendSuggestion, sendHotTopic 调用
			async sendTextMessageToAI(text) {
				const content = text.trim();
				if (!content || this.isWaitingForAi) return;

				// 1. 将用户消息显示在UI上
				const userMessage = {
					id: `local_text_${Date.now()}`,
					role: 'user',
					type: 'text',
					content: content // 使用传入的文本
				};
				this.chatHistory.push(userMessage);
				this.scrollToBottom();

				// 如果是从输入框发送的，清空输入框
				if (this.currentInput === content) {
					this.currentInput = '';
				}

				// 2. 显示“思考中”提示
				const thinkingMessageId = `ai_thinking_${Date.now()}`;
				const thinkingMessage = {
					id: thinkingMessageId,
					role: 'ai',
					type: 'text',
					content: '思考中...'
				};
				this.chatHistory.push(thinkingMessage);
				this.scrollToBottom();

				this.isWaitingForAi = true;

				try {
					// 3. 调用后端API
					const res = await sendAiMessage({
						content: content,
						type: 'text'
					});

					// 4. 移除“思考中”提示
					const thinkingIndex = this.chatHistory.findIndex(m => m.id === thinkingMessageId);
					if (thinkingIndex > -1) {
						this.chatHistory.splice(thinkingIndex, 1);
					}

					// 5. 显示AI的正式回复
					if (res.data && res.data.content) {
						const aiReply = {
							id: `ai_resp_${Date.now()}`,
							role: 'ai',
							type: 'text',
							content: res.data.content
						};
						this.chatHistory.push(aiReply);
					} else {
						throw new Error(res.data.msg || 'AI没有返回有效内容');
					}
				} catch (error) {
					// 6. 处理错误
					const thinkingIndex = this.chatHistory.findIndex(m => m.id === thinkingMessageId);
					if (thinkingIndex > -1) {
						this.$set(this.chatHistory, thinkingIndex, {
							id: thinkingMessageId,
							role: 'ai',
							type: 'text',
							content: '抱歉，我好像出错了，请稍后再试。'
						});
					}
					uni.showToast({
						title: '请求失败',
						icon: 'none'
					});
				} finally {
					this.isWaitingForAi = false;
					this.scrollToBottom();
				}
			},
			// sendMessage 方法
			async sendMessage() {
				this.sendTextMessageToAI(this.currentInput);
			},
			handleUploadImage() {
				uni.chooseImage({
					count: 1,
					success: (res) => {
						const tempFilePath = res.tempFilePaths[0];

						// 立即在UI上显示本地图片
						const localImageMsg = {
							id: `local_img_${Date.now()}`,
							role: 'user',
							type: 'image',
							content: tempFilePath,
						};
						this.chatHistory.push(localImageMsg);
						this.scrollToBottom();

						// 此处应调用上传服务（如七牛云），获取到网络URL
						// 为简化演示，我们假设上传成功并直接使用一个假URL
						this.uploadImageAndSend(tempFilePath);
					}
				});
			},
			async uploadImageAndSend(localPath) {
				// a. 显示“图片分析中...”
				const thinkingMessageId = `ai_thinking_${Date.now()}`;
				this.chatHistory.push({
					id: thinkingMessageId,
					role: 'ai',
					type: 'text',
					content: '图片分析中...'
				});
				this.scrollToBottom();
				this.isWaitingForAi = true;

				try {
					// b. 调用统一的上传方法
					uni.showLoading({
						title: '图片上传中...',
						mask: true
					});

					const uploadResult = await uploadFile({
						filePath: localPath,
						purpose: 'ai_ask_image', // 定义一个清晰的上传目的
						onProgress: (progress) => { // 可选的进度回调
							uni.showLoading({
								title: `上传中 ${progress}%`,
								mask: true
							});
						}
					});

					uni.hideLoading();

					const imageUrl = uploadResult.url;

					// c. 发送图片URL到AI后端
					const res = await sendAiMessage({
						content: imageUrl,
						type: 'image'
					});

					// d. 移除临时消息，显示AI回复
					const thinkingIndex = this.chatHistory.findIndex(m => m.id === thinkingMessageId);
					if (thinkingIndex > -1) this.chatHistory.splice(thinkingIndex, 1);

					if (res.data && res.data.content) {
						this.chatHistory.push({
							id: `ai_resp_img_${Date.now()}`,
							role: 'ai',
							type: 'text',
							content: res.data.content
						});
					} else {
						throw new Error(res.data.msg || 'AI未能对图片作出有效回复');
					}

				} catch (error) {
					// e. 统一错误处理
					uni.hideLoading();
					const thinkingIndex = this.chatHistory.findIndex(m => m.id === thinkingMessageId);
					if (thinkingIndex > -1) {
						this.$set(this.chatHistory, thinkingIndex, {
							id: thinkingMessageId,
							role: 'ai',
							type: 'text',
							content: '图片分析失败，请重试。'
						});
					}
					uni.showToast({
						title: error.message || '操作失败',
						icon: 'none'
					});
				} finally {
					this.isWaitingForAi = false;
					this.scrollToBottom();
				}
			},
			previewImage(url) {
				const imageUrls = this.chatHistory
					.filter(msg => msg.type === 'image')
					.map(msg => msg.content);
				uni.previewImage({
					urls: imageUrls,
					current: url
				});
			},
			scrollToBottom() {
				this.$nextTick(() => {
					if (this.chatHistory.length > 0) {
						const lastId = this.chatHistory[this.chatHistory.length - 1].id;
						this.scrollIntoViewId = `msg-${lastId}`;
					}
				});
			}
		}
	};
</script>

<style lang="scss" scoped>
	// 基础布局和导航栏
	.ai-ask-container {
		display: flex;
		flex-direction: column;
		height: 100vh;
		background-image: url(http://www.hacn86.cn/home_page/2025/07/01/1751363877418_20250701175757A253.png);
		background-size: 100% 100%;
	}

	.nav-bar {
		display: flex;
		align-items: center;
		justify-content: space-between;
		height: 44px;
		padding: 0 30rpx;
		position: fixed;
		width: 100%;
		top: 0;
		z-index: 10;
		box-sizing: border-box;

		.nav-title {
			font-size: 34rpx;
			font-weight: bold;
		}
	}

	.content-scroll {
		flex: 1;
		box-sizing: border-box;
		padding-top: 44px;
	}

	.content-scroll-header {
		margin: 0 30rpx;
		background-image: url("http://www.hacn86.cn/AI_QA/2025/07/10/1752136533776_20250710163533A005.png");
		background-size: 100% 100%;
		position: relative;
		z-index: 3;
	}

	// 头部区域
	.header-section {
		position: relative;
		display: flex;
		align-items: center;
		padding-left: 180rpx;
		padding-top: 50rpx;
		height: 150rpx;
		margin: 0 30rpx;

		.header-bg {
			position: absolute;
			top: 50rpx;
			left: 0;
			width: 100%;
			height: 150rpx;
			z-index: 1;
		}

		.header-content {
			position: relative;
			z-index: 2;
			display: flex;
			align-items: center;
		}

		.ai-avatar {
			width: 200rpx;
			height: auto;
			position: absolute;
			top: 0;
			left: -10rpx;
			z-index: 999;
		}

		.ai-hi {
			width: 100rpx;
			height: auto;
			position: absolute;
			top: 0;
			left: 150rpx;
			z-index: 999;
		}

		.slogan-main {
			font-size: 30rpx;
			font-weight: bold;
			color: #333;
		}
	}

	// 共同的section-title样式
	.section-title {
		display: flex;
		align-items: center;
		font-size: 28rpx;
		margin-bottom: 20rpx;
		color: #666;
	}

	// 热点区域
	.hot-topics-section {
		margin-top: -20rpx;
		z-index: 99;
		position: relative;
		padding: 40rpx 0; // 左右 padding 设为0，因为容器需要全宽以隐藏溢出部分

		.section-title {
			display: flex;
			justify-content: center; // 水平居中
			align-items: center; // 垂直居中
			width: 100%; // 宽度占满父容器，确保居中生效
			gap: 18rpx; // 设置元素之间的间距 (现代CSS方式)
			margin-bottom: 40rpx; // 保持和下方内容的间距

			.title-text {
				color: #000000;
				font-size: 28rpx;
				font-weight: 500; // 中等粗细
			}

			.title-slash {
				font-family: 'Courier New', Courier, monospace; // 使用等宽字体让斜杠更好看
				font-size: 30rpx;
				font-weight: bold;

				/* 关键：实现渐变色文字效果 */
				/* 1. 定义一个从深橙到浅橙的线性渐变背景 */
				background: linear-gradient(90deg, #F5A64A, #FFC87A);

				/* 2. 将背景裁剪为文字的形状 */
				-webkit-background-clip: text;
				background-clip: text;

				/* 3. 将文字颜色设为透明，这样渐变背景就能显现出来 */
				color: transparent;
			}
		}

		// 新增：父容器，用于裁剪溢出的滚动内容
		.topics-container {
			overflow: hidden;
			width: 100%;
		}

		// 修改：这是每一行的样式
		.topics-row {
			display: flex; // 使用 flex 布局让 tag 排成一行
			white-space: nowrap; // 强制不换行
			animation-name: scroll-left; // 默认应用向左滚动的动画
			animation-timing-function: linear;
			animation-iteration-count: infinite;

			// 给两行之间增加一些间距
			&:first-child {
				margin-bottom: 20rpx;
			}

			.topic-tag {
				margin-right: 20rpx;
				flex-shrink: 0; // 防止tag被压缩
			}

			// 新增：用于第二行，应用反向动画
			&.row-reverse {
				animation-name: scroll-right;
			}
		}
	}

	// 定义两个滚动动画

	// 动画1：向左无缝滚动
	@keyframes scroll-left {
		from {
			transform: translateX(0);
		}

		to {
			// 因为数据复制了一倍，所以移动50%的宽度后，视觉上是无缝的
			transform: translateX(-50%);
		}
	}

	// 动画2：向右无缝滚动
	@keyframes scroll-right {
		from {
			// 从-50%的位置开始
			transform: translateX(-50%);
		}

		to {
			// 回到0的位置
			transform: translateX(0);
		}
	}

	// 建议问题区域
	.suggestions-section {
		border-radius: 20rpx;
		margin: 0 30rpx;
		padding: 30rpx 24rpx;

		.section-title {
			font-size: 30rpx;
			font-weight: bold;
			color: #333;

			.title-icon {
				width: 50rpx;
				height: 36rpx;
				margin-right: 12rpx;
			}

			.refresh-btn {
				display: flex;
				align-items: center;
				margin-left: auto;
				font-size: 24rpx;
				color: #999;
				font-weight: normal;

				text {
					margin-left: 6rpx;
				}
			}
		}

		.suggestion-item {
			display: flex;
			justify-content: space-between;
			align-items: center;
			padding: 24rpx 0;
			font-size: 28rpx;
			color: #444;
			border-bottom: 1rpx solid #f5f5f5;

			&:last-child {
				border-bottom: none;
			}
		}
	}

	// 聊天记录区域
	.chat-history {
		padding: 40rpx 30rpx;
		padding-bottom: 100rpx;

		.chat-bubble-wrapper {
			display: flex;
			margin-bottom: 40rpx;

			.chat-ai {
				width: 80rpx;
				height: 80rpx;
				flex-shrink: 0;
			}

			.chat-avatar {
				width: 80rpx;
				height: 80rpx;
				border-radius: 50%;
				flex-shrink: 0;
			}

			.chat-bubble {
				position: relative;
				padding: 20rpx 24rpx;
				max-width: calc(100% - 180rpx);
				font-size: 30rpx;
				border-radius: 20rpx;
				word-break: break-word;

				.chat-image {
					max-width: 100%;
					border-radius: 12rpx;
					display: block; // 消除图片底部空隙
				}
			}

			&.ai {
				justify-content: flex-start;

				.chat-avatar {
					margin-right: 20rpx;
				}

				.chat-bubble {
					background-color: #fff;
					color: #333;
					border-top-left-radius: 0;
				}
			}

			&.user {
				justify-content: flex-end;

				.chat-avatar {
					margin-left: 20rpx;
				}

				.chat-bubble {
					background-color: #A9DCFF;
					color: #000;
					border-top-right-radius: 0;
				}
			}
		}
	}

	// 底部输入栏
	.input-bar {
		display: flex;
		align-items: center;
		padding: 16rpx 20rpx;
		background-color: #fff;
		// border-top: 1rpx solid #e7e7e7;
		position: fixed;
		bottom: 0;
		left: 0;
		width: 100%;
		box-sizing: border-box;
		padding-bottom: calc(16rpx + env(safe-area-inset-bottom));

		.input-wrapper {
			flex: 1;
			background-color: #f7f7f7;
			border-radius: 36rpx;
			padding: 0 24rpx;
			height: 72rpx;
			display: flex;
			align-items: center;

			.submit {
				width: 100rpx;
			}

			input {
				width: 100%;
				height: 100%;
				font-size: 28rpx;
			}
		}
	}
</style>